#!/usr/bin/python
# -*- coding: utf-8 -*-


OF13Type=[
     "HELLO",
     "ERROR",
     "ECHO_REQUEST",
     "ECHO_REPLY",
     "EXPERIMENTER",
     "FEATURES_REQUEST",
     "FEATURES_REPLY",
     "GET_CONFIG_REQUEST",
     "GET_CONFIG_REPLY",
     "SET_CONFIG",
     "PACKET_IN",
     "FLOW_REMOVED",
     "PORT_STATUS",
     "PACKET_OUT",
     "FLOW_MOD",
     "PORT_MOD",
     "STATS_REQUEST",
     "STATS_REPLY",
     "BARRIER_REQUEST",
     "BARRIER_REPLY",
     "QUEUE_GET_CONFIG_REQUEST",
     "QUEUE_GET_CONFIG_REPLY",
     "GROUP_MOD",
     "TABLE_MOD",
     "ROLE_REQUEST",
     "ROLE_REPLY",
     "GET_ASYNC_REQUEST",
     "GET_ASYNC_REPLY",
     "SET_ASYNC",
     "METER_MOD"
     # "ROLE_STATUS",
     # "TABLE_STATUS",
     # "REQUESTFORWARD",
     # "BUNDLE_CONTROL",
     # "BUNDLE_ADD_MESSAGE",
     # "CONTROLLER_STATUS"
]


#type = 0
HELLO = {
    "version":"byte",
    "type":"byte",
    "length":"short",
    "xid":"long"
}

#type = 1
ERROR={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "errType":"short",
    "code":"short",
    "data":"byte[]"
}

#type = 2
ECHO_REQUEST={
    "version":"byte",
    "type":"byte",
    "length":"short",
    "xid":"long",
    "data":"byte[]"
}

#type = 3
ECHO_REPLY={
    "version":"byte",
    "type":"byte",
    "length":"short",
    "xid":"long",
    "data":"long"
}

#type = 4
EXPERIMENTER={

}

#type = 5
FEATURES_REQUEST={
    "version":"byte",
    "type":"byte",
    "length":"short",
    "xid":"long"
}

#type = 6
FEATURES_REPLY={
    "version":"byte",
    "type":"byte",
    "length":"short",
    "xid":"long",
    "datapathId":"long",
    "nBuffers":"long",
    "nTables":"short",
    "auxiliaryId":"short",
    "capabilities":"int",
    "reserved":"long"
}

#type = 7
GET_CONFIG_REQUEST={
    "version":"byte",
    "type":"byte",
    "length":"short",
    "xid":"long",
}

#type = 8
GET_CONFIG_REPLY={
    "version":"byte",
    "type":"byte",
    "length":"short",
    "xid":"long",
    "flags":"int",
    "missSendLen":"int"
}

#type = 9
SET_CONFIG={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "flags":"int",
    "missSendLen":"int"
}

#type = 10
PACKET_IN={
    "version":"byte",
    "type":"byte",
    "length":"short",
    "xid":"long",
    "bufferId":"int",
    "totalLen":"int",
    "reason":"byte",
    "tableId":"byte",
    "cookie":"long",
    "match":"byte[]",
    "data":"byte[]"
}

#type = 11
FLOW_REMOVED={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "cookie":"long",
    "priority":"int",
    "reason":"short",
    "tableId":"byte",
    "durationSec":"long",
    "durationNsec":"long",
    "idleTimeout":"int",
    "hardTimeout":"int",
    "packetCount":"long",
    "byteCount":"long",
    "match":"byte[]"
}

#type = 12
PORT_STATUS={
    "version":"byte",
    "type":"byte",
    "length":"short",
    "xid":"long",
    "reason":"byte",
    "port_no":"int",
    "hw_addr":"long",
    "name":"String",
    "config":"int",
    "state":"int",
    "curr":"int",
    "advertised":"int",
    "supported":"int",
    "peer":"int",
    "curr_speed":"long",
    "max_speed":"long"
}

#type = 13
PACKET_OUT={
    "version":"byte",
    "type":"byte",
    "length":"short",
    "xid":"long",
    "bufferId":"int",
    "inPort":"int",
    "actionLen":"short",
    "action":"byte[]",
    "data":"byte[]"
}

#type = 14
FLOW_MOD={
    "version":"byte",
    "type":"byte",
    "length":"short",
    "xid":"long",
    "cookie":"long",
    "cookieMask":"long",
    "tableId":"byte",
    "command":"byte",
    "idleTimeout":"int",
    "hardTimeout":"int",
    "priority":"int",
    "bufferId":"int",
    "outPort":"int",
    "outGroup":"int",
    "flags":"short",
    "match":"byte[]",
    "instructions":"byte[]"
}

#type = 15
GROUP_MOD={
    "version":"byte",
    "type":"byte",
    "length":"short",
    "xid":"long",
    "command":"short",
    "groupType":"byte",
    "group":"int",
    "buckets":"byte[]"
}

#type = 16
PORT_MOD={
    "version":"byte",
    "type":"byte",
    "length":"short",
    "xid":"long",
    "portNo":"int",
    "hwAddr":"long",
    "config":"long",
    "mask":"long",
    "advertise":"long"
}

#type = 17
TABLE_MOD={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "tableId":"byte",
    "config":"long"
}

#type = 18
# MultipartReq :

FLOW_REQUEST={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "statsType":"short",
    "flags":"int",
    "tableId":"short",
    "outPort":"long",
    "outGroup":"long",
    "cookie":"long",
    "cookieMask":"long",
    "match":"byte[]"
}

METER_REQUEST={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "statsType":"short",
    "flags":"int",
    "meterId":"long"
}

PORT_REQUEST={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "statsType":"short",
    "flags":"int",
    "portNo":"long"
}

DESC_REQUEST={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "statsType": "short",
    "flags": "int",
}

PORT_DESC_REQUEST={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "statsType": "short",
    "flags": "int",
}

METER_FEATURES_REQUEST={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "statsType": "short",
    "flags": "int",
}

TABLE_FEATURES_REQUEST={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "statsType": "short",
    "flags": "int",
    "entries": "byte[]"
}

#type = 18
MultipartReq = {
    "PORT_DESC_REQUEST":PORT_DESC_REQUEST,
    "DESC_REQUEST":DESC_REQUEST,
    "METER_REQUEST":METER_REQUEST,
    "PORT_REQUEST":PORT_REQUEST,
    "FLOW_REQUEST":FLOW_REQUEST,
    "METER_FEATURES_REQUEST":METER_FEATURES_REQUEST,
    "TABLE_FEATURES_REQUEST":TABLE_FEATURES_REQUEST
}

#type = 19
# MultipartRes :

PORT_DESC_REPLY={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "statsType": "short",
    "flags": "int",
    "entries":"byte[]"
}

DESC_REPLY={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "statsType": "short",
    "flags": "int",
    "mfrDesc": "byte[]",
    "hwDesc": "byte[]",
    "swDesc": "byte[]",
    "serialNum": "byte[]",
    "dpDesc": "byte[]"
}

METER_REPLY={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "statsType": "short",
    "flags": "int",
    "entries": "byte[]"
}

PORT_REPLY={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "statsType": "short",
    "flags": "int",
    "entries": "byte[]"
}

FLOW_REPLY={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "statsType": "short",
    "flags": "int",
    "entries": "byte[]"
}

METER_FEATURES_REPLY={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "statsType": "short",
    "flags": "int",
    "maxMeter": "long",
    "bandTypes": "long",
    "capabilities": "long",
    "maxBands": "short",
    "maxColor": "short"
}

TABLE_FEATURES_REPLY={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "statsType": "short",
    "flags": "int",
    "entries": "byte[]"
}

#type = 19
MultipartRes = {
    "PORT_DESC_REPLY":PORT_DESC_REPLY,
    "DESC_REPLY":DESC_REPLY,
    "METER_REPLY":METER_REPLY,
    "PORT_REPLY":PORT_REPLY,
    "FLOW_REPLY":FLOW_REPLY,
    "METER_FEATURES_REPLY":METER_FEATURES_REPLY,
    "TABLE_FEATURES_REPLY":TABLE_FEATURES_REPLY
}

#type = 20
BARRIER_REQUEST={
    "version":"byte",
    "type":"byte",
    "length":"short",
    "xid":"long"
}

#type = 21
BARRIER_REPLY={
    "version":"byte",
    "type":"byte",
    "length":"short",
    "xid":"long"
}

#type = 22
QUEUE_GET_CONFIG_REQUEST={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "port": "long",
}

#type = 23
QUEUE_GET_CONFIG_REPLY={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "port":"long",
    "queues":"byte[]"
}

#type = 24
ROLE_REQUEST={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "role": "int",
    "generationId": "long"
}

#type = 25
ROLE_REPLY={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "role": "int",
    "generationId": "long"
}

#type = 26
GET_ASYNC_REQUEST={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
}

#type = 27
GET_ASYNC_REPLY={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "packetInMaskEqualMaster": "long",
    "packetInMaskSlave": "long",
    "portStatusMaskEqualMaster": "long",
    "portStatusMaskSlave": "long",
    "flowRemovedMaskEqualMaster": "long",
    "flowRemovedMaskSlave": "long"
}

#type = 28
SET_ASYNC={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "packetInMaskEqualMaster": "long",
    "packetInMaskSlave": "long",
    "portStatusMaskEqualMaster": "long",
    "portStatusMaskSlave": "long",
    "flowRemovedMaskEqualMaster": "long",
    "flowRemovedMaskSlave": "long"
}

#type = 29
METER_MOD={
    "version": "byte",
    "type": "byte",
    "length": "short",
    "xid": "long",
    "command":"int",
    "flags":"int",
    "meterId":"long",
    "meters":"byte[]"
}


OF13TypeFiel= {
    "HELLO":HELLO,
    "ROLE_REQUEST":ROLE_REQUEST,
    "ROLE_REPLY":ROLE_REPLY,
    "BARRIER_REQUEST":BARRIER_REQUEST,
    "BARRIER_REPLY":BARRIER_REQUEST,
    "ECHO_REPLY":ECHO_REPLY,
    "FEATURES_REQUEST":FEATURES_REQUEST,
    "FEATURES_REPLY":FEATURES_REPLY,
    "PORT_STATUS":PORT_STATUS
}

testController = [
    "HELLO",
    "ROLE_REPLY",
    "BARRIER_REPLY",
    "FEATURES_REQUEST",
    "FEATURES_REPLY",
    "PORT_STATUS",
    "STATS_REPLY",
    "PACKET_IN",
    "ECHO_REQUEST",
    "ECHO_REPLY",
    "FLOW_REMOVED",
    "ERROR",
    "PORT_STATUS"
]

testSwitch = [
    "HELLO",
    "FEATURES_REQUEST",
    "BARRIER_REQUEST",
    "METER_MOD",
    "PACKET_OUT",
    "FLOW_MOD",
    "GROUP_MOD",
    "TABLE_MOD",
    "SET_CONFIG",
    "SET_ASYNC",
    "GET_ASYNC_REQUEST",
    "GET_CONFIG_REQUEST",
    "QUEUE_GET_CONFIG_REQUEST",
    "ECHO_REQUEST",
    "ECHO_REPLY",
    "ERROR",
    "STATS_REQUEST",
    "ROLE_REQUEST",
    "STATS_REQUEST"
]

hasChild = {
    "STATS_REQUEST":MultipartReq,
    "STATS_REPLY":MultipartRes
}

version = ['1.3']

testTarget={
    'controller':testController,
    'switch':testSwitch
}


dup_nums = [2,10]

delay_times = [100,1000]

drop_time = [1]

actions = {
    'DROP':drop_time,
    'DELAY':delay_times,
    'DUPLICATE':dup_nums
}


'''
Byte.MAX_VALUE:127
Byte.MIN_VALUE:-128
Short.MAX_VALUE:32767
Short.MIN_VALUE:-32768
Integer.MAX_VALUE:2147483647
Integer.MIN_VALUE:-2147483648
Long.MAX_VALUE:9223372036854775807
Long.MIN_VALUE:-9223372036854775808
'''
FieldValues = {
	'byte':[0, -1, -128, 127],
	'short':[0, -1, 32000, 32767, -32768],
	'int':[0,-1,-65535,65535,2147483647,-2147483648],
	'long':[0,-1,-65535,65535,4294967293,8882949672954,9223372036854775807,-9223372036854775808],
	'String':["", "0", "000000000", "fffffffff"],
    'byte[]':['random1','random2','random3','random4']
}


'''String ofVersion,String ofType,String childOFType,String action,String field,String actionValue'''
def packetStraGen():
    stras = []

    '''MODIFY'''
    for tarkey, tarval in testTarget.items():#testWhich
        for type in tarval:#ofType
            if type in hasChild.keys():
                for child, childV in hasChild[type].items():#childType
                    for field, fieldV in OF13TypeFiel[childV].items():  # field
                        for value in FieldValues[fieldV]:  # actionValue
                            stra = ("ofVersion:" + '1.3'
                                    + ",ofType:" + type
                                    + ",childType:"+ child
                                    + ",testWhich:" + tarkey
                                    + ",action:" + "MODIFY"
                                    + ",field:" + field
                                    + ",actionValue:" + str(value))
                            stras.append(stra)
            else:
                for field, fieldV in OF13TypeFiel[type].items():  # field
                    for value in FieldValues[fieldV]:  # actionValue
                        stra = ("ofVersion:" + '1.3'
                                + ",ofType:" + type
                                + ",childType:" + '*'
                                + ",testWhich:" + tarkey
                                + ",action:" + "MODIFY"
                                + ",field:" + field
                                + ",actionValue:" + str(value))
                        stras.append(stra)

    '''DELAY, DROP, DUPLICATE'''
    # for tarkey, tarval in testTarget.items():#testWhich
    #     for type in tarval:#ofType
    #         if type in hasChild:
    #             for child in hasChild[type]:#childType
    #                 for actionKey, action in actions:
    #                     for value in action:
    #                         stra = ("ofVersion:" + '1.3'
    #                                 + ",ofType:" + type
    #                                 + ",childType:" + child
    #                                 + ",testWhich:" + tarkey
    #                                 + ",action:" + actionKey
    #                                 + ",field:" + '*'
    #                                 + ",actionValue:" + str(value))
    #                         stras.append(stra)
    #
    #         else:
    #             for actionKey, action in actions:
    #                 for value in action:
    #                     stra = ("ofVersion:" + '1.3'
    #                             + ",ofType:" + type
    #                             + ",childType:" + '*'
    #                             + ",testWhich:" + tarkey
    #                             + ",action:" + actionKey
    #                             + ",field:" + '*'
    #                             + ",actionValue:" + str(value))
    #                     stras.append(stra)


    with open('strategies.txt', 'w') as f:
        for stra in stras:
            f.write(stra+'\n')


if __name__ == "__main__":
    packetStraGen()